package pile.customer.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import pile.customer.params.ReceivingInformation;
import pile.customer.service.IUserInformationService;
import pile.customer.service.IUserService;

import javax.annotation.PostConstruct;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@ServerEndpoint("/userWebSocket/{openId}/{channel}/{phone}")
@Slf4j
public class UserWebSocketServerUtil {

    private Session session;
    private static CopyOnWriteArraySet<UserWebSocketServerUtil> webSocketSet = new CopyOnWriteArraySet<>();
    private static ConcurrentHashMap<String, UserWebSocketServerUtil> webSocketMap  = new ConcurrentHashMap<>();
    private String openId = null;

    private Integer channel = null;

    private String phone = null;

    private static IUserInformationService userInformationService ;

    private static IUserService userService; ;

    @Autowired
    private IUserInformationService autowiredUserInformationService;

    @Autowired
    private IUserService autowiredUserService;



    @PostConstruct
    public void init() {
        userInformationService = autowiredUserInformationService;

        userService = autowiredUserService;
    }

    @OnOpen
    public void onOpen(Session session, @PathParam("openId") String openId,
                       @PathParam("channel") Integer channel,
                       @PathParam("phone") String phone ){
        this.session = session;
        this.openId = openId;
        this.channel = channel;
        this.phone = phone;
        
        if(openId==null){
            return;
        }
        if(webSocketMap .containsKey(openId)){
            webSocketMap .remove(openId);
            webSocketMap .put(openId,this);
        }else{
            webSocketMap .put(openId,this);
            webSocketSet.add(this);
        }

        try{
            //判断链接的客户是否存在
           userService.userLogin(openId,channel,phone);
        }catch (Exception e){
            log.error("用户登录报错:"+e);
        }


        log.info("【websocket消息】有新用户的连接，总数：{}",webSocketMap.size());
    }

    @OnClose
    public void onClose(){
        if(webSocketMap.containsKey(openId)){
            webSocketMap.remove(openId);
            //从set中删除
            webSocketSet.remove(this);
        }

        //修改用户状态改为 离线
        userService.userOffline(openId);
        log.info("【websocket消息】用户连接断开，总数：{}",webSocketSet.size());
    }

    @OnMessage
    public void onMessage(String message) throws Exception {

        ReceivingInformation receivingInformation = new ReceivingInformation();

        JSONObject jsonObject = JSON.parseObject(message);

        String messageStr =  jsonObject.getString("message");

        String customerServiceAccount =  jsonObject.getString("customerServiceAccount");
        String channel = jsonObject.getString("channel");
        //消息类型
        String messageType = jsonObject.getString("messageType");

        //是否自动回复
        Boolean automaticReply = jsonObject.getBoolean("automaticReply");
        if(automaticReply==null){
            automaticReply = false;
        }
        //获取自动回复内容
        String reply = jsonObject.getString("reply");
        //信息
        receivingInformation.setMessage(messageStr);
        //openid
        receivingInformation.setOpenId(openId);
        //客服账号
        receivingInformation.setCustomerServiceAccount(customerServiceAccount);
        //发送时间
        receivingInformation.setSendingTime(new Date());
        //是否自动回复
        receivingInformation.setAutomaticReply(automaticReply);
        //自动回复内容
        receivingInformation.setReply(reply);
        //渠道
        if(StringUtils.isEmpty(channel)){
            channel = "1";
        }
        if(StringUtils.isEmpty(messageType)){
            messageType = "1";
        }
        receivingInformation.setChannel(Integer.valueOf(channel));
        receivingInformation.setMessageType(Integer.valueOf(messageType));
        userInformationService.processingMessages(receivingInformation);

        log.info("【websocket消息】收到用户发来的消息：{}",message);
    }

    public void sendMessage(String message){
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    /**
     * 发送自定义消息
     * */
    public  void sendInfo(String message,String openId) throws Exception {

        //log.info("发送消息到:"+openId+"，报文:"+message);

            if(webSocketMap.containsKey(openId)){
                webSocketMap.get(openId).sendMessage(message);
            }else{

                log.warn("用户不在线，由客服发送消息:"+ message);
            }
    }

    //根据openId 查询是否存在链接
    public  boolean isOnLine(String openId){
        if(webSocketMap.containsKey(openId)){
            return true;
        }else{
            return false;
        }
    }
}
